package cn.com.util;

import cn.com.Enum.UserAuth;
import cn.com.db.Jwt.Header;
import cn.com.db.Jwt.JWT;
import cn.com.db.Jwt.Payload;
import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;

public class TokenUtil {

    private static final String SHA512="SHA-512";

    private static final String SHA256="SHA-256";

    private static final String hs256key="";

    private static final String secret="root";

    public static String createToken(String userId,UserAuth auth){
        JWT jwt=new JWT();
//        jwt.setAud(userId);
//        jwt.setAuth(auth);
//        jwt.setIat(TimeUtil.getNowTime());
//        jwt.setExp(TimeUtil.getTokenExp());
        String base64Part=Base64(JSON.toJSONString(jwt),true);
        String secretPart=SHA(addSalt(base64Part,""),SHA256);
        return base64Part+"."+secretPart;
    }

    public static JWT parseToken(String token)
            throws UnsupportedEncodingException,
            TokenExpiredException,InvalidClaimException,Exception{
        DecodedJWT decodedJWT=null;
        try {
            Algorithm algorithm=Algorithm.HMAC256(secret);
            JWTVerifier verifier= com.auth0.jwt.JWT.require(algorithm).build();
            decodedJWT= verifier.verify(token);
        }catch (UnsupportedEncodingException e) {
            throw e;
        }catch (TokenExpiredException e){
            throw e;
        }catch (InvalidClaimException e){
            throw e;
        }
        if (decodedJWT==null){
            throw new Exception("令牌错误,解析异常");
        }
        JWT jwt=new JWT();
        String header=Base64(decodedJWT.getHeader(),false);
        String payload=Base64(decodedJWT.getPayload(),false);
        String verify=decodedJWT.getSignature();
        jwt.setHeader(JSON.parseObject(header, Header.class));
        jwt.setPayload(JSON.parseObject(payload, Payload.class));
        jwt.setVerify(verify);
        jwt.setToken(token);
        return jwt;
    }




    private static String addSalt(String base,String md5){
        String material=null;
        if (md5.length()==0){
            material="AA"+base+"ZZ";
        }else {
            int i= Math.round(md5.length()/2);
            material=md5.substring(0,i)+base+md5.substring(i);
        }
        return material;
    }

    private static String SHA(final String strText, final String strType)
    {
        // 返回值
        String strResult = null;

        // 是否是有效字符串
        if (strText != null && strText.length() > 0)
        {
            try
            {
                // SHA 加密开始
                // 创建加密对象 并傳入加密類型
                MessageDigest messageDigest = MessageDigest.getInstance(strType);
                // 传入要加密的字符串
                messageDigest.update(strText.getBytes());
                // 得到 byte 類型结果
                byte byteBuffer[] = messageDigest.digest();

                // 將 byte 轉換爲 string
                StringBuffer strHexString = new StringBuffer();
                // 遍歷 byte buffer
                for (int i = 0; i < byteBuffer.length; i++)
                {
                    String hex = Integer.toHexString(0xff & byteBuffer[i]);
                    if (hex.length() == 1)
                    {
                        strHexString.append('0');
                    }
                    strHexString.append(hex);
                }
                // 得到返回結果
                strResult = strHexString.toString();
            }
            catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
            }
        }

        return strResult;
    }

    public static String HMACSHA256(byte[] data, byte[] key)
    {
        try  {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(signingKey);
            return byte2hex(mac.doFinal(data));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String byte2hex(byte[] b)
    {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b!=null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1)
                hs.append('0');
            hs.append(stmp);
        }
        return hs.toString().toUpperCase();
    }



    public static String Base64(String s,boolean encoder){
        if (encoder){
            Base64.Encoder encoder1=Base64.getEncoder();
            return encoder1.encodeToString(s.getBytes());
        }else {
            Base64.Decoder decoder=Base64.getDecoder();
            return new String(decoder.decode(s));
        }
    }


    public static void main(String[] args) {
//        String token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImVtYWlsIjoiIiwidW5pb25pZCI6Im80eTRDdnhpWExtVzRfWkFVMUo5a3lxU005QjQiLCJpZCI6IjVhYWZiMTMxYmVjN2VkMDAwMWMxODRkMyIsImNsaWVudElkIjoiNWE5N2VkZmJmODYzNWEwMDAxODU1MWEyIn0sImlhdCI6MTUyMzc3ODMyMCwiZXhwIjoxNTI1MDc0MzIwfQ.owAIjllsbO-TfaCndIvXN6YWyMdlu8fNKjWBdMXswQ0";
//        try {
//            Algorithm algorithm=Algorithm.HMAC256("");
//            JWTVerifier verifier= com.auth0.jwt.JWT.require(algorithm)
//                    .build();
//            DecodedJWT jwt=verifier.verify(token);
//            System.out.println(JSON.toJSONString(jwt));
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
//        try {
//            Algorithm algorithm=Algorithm.HMAC256("yue");
//            String token=com.auth0.jwt.JWT.create()
//                    .withIssuedAt(new Date(TimeUtil.getNowTime()))
//                    .withExpiresAt(new Date(TimeUtil.getNowTime()+100L))
//                    .sign(algorithm);
//            System.out.println(token);
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }

        String token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MjM3ODA0MjksImlhdCI6MTUyMzc4MDQyOX0.9MgaFZOy6AcliamumTbzaBNeB9blD5lXKXU8yrURC8c";
        try {
            Algorithm algorithm=Algorithm.HMAC256("yue");
            JWTVerifier verifier= com.auth0.jwt.JWT.require(algorithm).build();
            DecodedJWT decodedJWT= verifier.verify(token);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }catch (TokenExpiredException e){

        }catch (InvalidClaimException e){

        }
    }
}
